package workers

import (
	"encoding/json"
	"fmt"
	"github.com/go-cinch/common/log"
	"net/url"
	"time"
)

func RunTikTokExploreWorker(count int) {
	for categoryType, name := range categoryTypeMap {
		log.Info("worker is running %d , categoryType %s, name %s", count, categoryType, name)
		tiktokExploreWorker = NewTikTokExploreWorker()
		tiktokExploreWorker.run(count, categoryType)
	}

}

func (w *TikTokExploreWorker) getUrl(categoryType string) string {
	var params = url.Values{}
	params.Add("aid", "1988")
	params.Add("app_language", "en")
	params.Add("app_name", "tiktok_web")
	params.Add("browser_language", "en-US")
	params.Add("battery_info", "1")
	params.Add("browser_name", "Mozilla")
	params.Add("browser_online", "true")
	params.Add("browser_platform", "Linux x86_64")
	params.Add("browser_version", "5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36")
	params.Add("channel", "tiktok_web")
	params.Add("cookie_enabled", "true")
	params.Add("categoryType", categoryType)
	//params.Add("device_id", crypto.RandomStringNumber(19))
	params.Add("device_platform", "web_pc")
	params.Add("focus_state", "true")
	params.Add("from_page", "hashtag")
	params.Add("count", "16")
	params.Add("is_fullscreen", "false")
	params.Add("is_page_visible", "true")
	params.Add("language", "en")
	params.Add("os", "mac")
	params.Add("priority_region", "")
	params.Add("referer", "https://www.tiktok.com/explore?lang=en")
	params.Add("region", "US")
	params.Add("screen_height", "1120")
	params.Add("screen_width", "1792")
	params.Add("tz_name", "Europe/Bucharest")
	params.Add("webcast_language", "en")
	u, _ := url.ParseRequestURI("https://www.tiktok.com")
	u.Path = "/api/explore/item_list/"
	u.RawQuery = params.Encode()
	return fmt.Sprintf("%v", u)
}

func (w *TikTokExploreWorker) worker(categoryType string) {
	c := newCollector()
	c.SetRequestTimeout(30 * time.Second)
	u := w.getUrl(categoryType)
	proxy := getProxy()
	if proxy != "" {
		c.SetProxy(proxy)
	}

	c.OnError(func(r *colly.Response, err error) {
		log.Error("error %s | proxy %s | retrying", err.Error(), proxy)
		r.Request.Retry()
	})

	c.OnResponse(func(r *colly.Response) {
		var resp TikTokResp
		if r.StatusCode != 200 {
			log.Error("status code is not 200 %d | tag %s", r.StatusCode, categoryType)
			w.incrError()
			return
		}
		if err := json.Unmarshal(r.Body, &resp); err != nil {
			log.Error("TikTokExploreWorker | unmarshal error %s | resp body %s |", err.Error(), string(r.Body))
			w.incrError()
			return
		}
		if resp.StatusCode > 0 {
			log.Error("status code is not 0 %d | proxy %s", resp.StatusCode, proxy)
			w.incrError()
			return
		}

		items := lo.Filter(resp.ItemList, func(item TikTokRespItem, _ int) bool {
			return item.Stats.DiggCount > 25000
		})
		if len(items)*3 < len(resp.ItemList) {
			log.Error("digg count is less than 25000 length %d total %d | skipping  ", len(items), len(resp.ItemList))
			return
		}
		for _, item := range resp.ItemList {
			if item.AuthorStats.FollowerCount > 10000 {
				log.Info("follower count is more than 10000 | author name %s, unique id %s resp.Cursor %s ", item.Author.Nickname, item.Author.UniqueID, resp.Cursor)
				tikTok := &models.TikTok{}
				tikTok.Handler = item.Author.UniqueID
				if !tikTok.IsJobScraped() {
					log.Info("tiktok job is not scraped, pushing to tiktokJobQueue | author name %s, unique id %s", item.Author.Nickname, item.Author.UniqueID)
					redis.LPush(tiktokJobQueue, item.Author.UniqueID)
				}
			}
			if item.Stats.DiggCount > 250000 {
				log.Info("digg count is more than 250000 | author name %s, unique id %s resp.Cursor %s ", item.Author.Nickname, item.Author.UniqueID, resp.Cursor)
				tikTok := &models.TikTok{}
				tikTok.Handler = item.Author.UniqueID
				if !tikTok.IsJobScraped() {
					redis.LPush(tiktokJobQueue, item.Author.UniqueID)
				}
			}
		}

	})
	c.OnRequest(func(r *colly.Request) {
		r.Headers.Set("referer", "https://www.tiktok.com/explore?lang=en")
		r.Headers.Set("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7")
		r.Headers.Set("accept-language", "en-CA,en;q=0.9")
		r.Headers.Set("cache-control", "no-cache")
		r.Headers.Set("dnt", "1")
		r.Headers.Set("pragma", "no-cache")
		r.Headers.Set("sec-fetch-dest", "document")
		r.Headers.Set("sec-fetch-mode", "navigate")
		r.Headers.Set("sec-fetch-site", "none")
		r.Headers.Set("sec-fetch-user", "?1")
		log.Info("Visiting %s ", r.URL.String())
	})
	c.Visit(u)
}
